iT邦幫忙

1

🛠️ 解決 DLL 同步與版本錯誤問題:我為什麼把 SQLite.Interop.dll 當成神主牌

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20250710/20155103HGAOiuDnIN.png

📌 問題從一顆 DLL 開始

某天,我在維護正式機的 ASP.NET WebForm 系統(EIP)時,發現一件奇怪的事:

kgeip\bin\x64\SQLite.Interop.dll 的修改時間居然是 2024/10/29,但它卻能正常運作。對照本機打包時的 DLL(版本為 2025/6/30),代表我 Build 完根本沒有正確覆蓋到正式機的版本。

原本以為是小事,沒想到這背後踩了好幾個坑。

🧱 老專案、非託管 DLL 與 NuGet 的誤會:一次搞懂 SQLite.Interop.dll 的部署策略

🗂️ 老 WebForm 專案裡的 DLL 難題

在處理一個 ASP.NET Web Site 專案(不是 Web Application)時,我遇到錯誤訊息:

System.DllNotFoundException: 無法載入 DLL 'SQLite.Interop.dll':找不到指定的模組

這讓我重新面對一個老問題:非託管 DLL(native DLL)在 WebForm 專案中的管理與部署問題。特別是這些 DLL 來自 NuGet 時,還原機制比預期複雜很多。

🧩 SQLite 套件帶來的多重依賴問題

我的 packages.config 指定版本如下:

<package id="System.Data.SQLite" version="1.0.113.6" />
<package id="System.Data.SQLite.Core" version="1.0.113.6" />
<package id="System.Data.SQLite.Linq" version="1.0.113.6" />

這些會還原出:

類型 描述
System.Data.SQLite.dll .NET 託管 DLL
SQLite.Interop.dll Native C++ DLL(需依平台複製)

但問題是,SQLite.Interop.dll 並不會自動複製進 /bin

🚧 光還原套件還不夠

我原以為執行 nuget restore 就夠,實際卻不是:

指令 功能
nuget restore 還原套件到 /packages
Update-Package -Reinstall 強制將 DLL 安裝至 /bin 並更新 web.config

這點在 WebSite 專案特別重要,因為 NuGet 並不會自動處理 native DLL 複製。

🔄 自動處理 native DLL 的 bat 實作

我加進 build.bat 的處理:

:: 建立 bin 子資料夾
if not exist kgeip\bin\x64 mkdir kgeip\bin\x64
if not exist kgeip\bin\x86 mkdir kgeip\bin\x86

:: 搜尋並複製 SQLite.Interop.dll
for /R %%I in (SQLite.Interop.dll) do (
    echo %%~dpI | findstr /I "\\x64\\" >nul && (
        copy /Y "%%~I" kgeip\bin\x64\ >nul
    )
    echo %%~dpI | findstr /I "\\x86\\" >nul && (
        copy /Y "%%~I" kgeip\bin\x86\ >nul
    )
)

搭配 web.config 的 probing 設定:

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <probing privatePath="bin\x64;bin\x86"/>
  </assemblyBinding>
</runtime>

這樣就能在執行期自動載入對應平台的 DLL。

🔥 為什麼一定要 Update-Package -Reinstall?

即使還原了套件,只要 /bin 被清空,會立刻遇到以下錯誤:

System.IO.FileNotFoundException: 找不到 System.Data.SQLite.dll
System.DllNotFoundException: 無法載入 SQLite.Interop.dll

只有 Update-Package -Reinstall 能正確還原這些 DLL 到 /bin,並處理相依關係。

✅ 實務建議

環境 建議做法
開發機 用套件管理器,定期 Reinstall
正式機(WebSite) 手動複製 DLL,搭配 bat 維護 native DLL
正式機(WebApp) 可用 MSBuild 搭配 .csproj 自動處理

🔃 意外的 git 錯誤與系統鎖定問題

修改完 bat、重建完專案後,我打算 pull 最新的主線代碼,卻報錯:

Unable to pull when changes are present on your branch.

我先執行:

git restore kgeip/Bin/EDAPortal.dll

正常。

但當我想還原 Interop 檔案時:

git restore kgeip/Bin/x86/SQLite.Interop.dll

卻報錯:

error: unable to unlink old 'kgeip/Bin/x86/SQLite.Interop.dll': Invalid argument

我停用 IIS 才成功解除鎖定。

🤖 自動化建置腳本優化

我重新整理 build.bat,加入以下功能:

  • 自動尋找 msbuild.exe
  • 建置 kgeip.sln
  • 複製 DLL 到 kgeip\bin
  • 複製固定版本 SQLite.Interop.dll(x86/x64)
  • 提示錯誤與自動建立資料夾

⚠️ .gitignore 的例外追蹤技巧

我希望能 commit SQLite.Interop.dll,就加入:

!kgeip/Bin/x86/
!kgeip/Bin/x86/SQLite.Interop.dll

並強制加入:

git add -f kgeip/Bin/x86/SQLite.Interop.dll

讓 git 忽略整個 bin 的同時,仍能追蹤這個重要 DLL。

💡 適合詢問 GPT 的 Prompt

  • 「NuGet 還原後 DLL 沒進 bin,要怎麼處理?」
  • 「如何判斷 native DLL 是否要自動複製?」
  • 「git restore DLL 報 Invalid argument 怎麼排解?」
  • 「Web Site 專案該怎麼正確部署 SQLite.Interop.dll?」

圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言